<?php

namespace App\Models;

use App\Models\ComModel;

class UserModel extends ComModel
{

    public $tablename;

    public function __construct()
    {
        parent::__construct();
        $this->tablename = 'user';
    }

    //验证
    private function _validate($data, $id = 0)
    {
        $data = esc($data);

        $config = $this->getConfig();
        $groups = $this->getGroups();

        if (!isset($data) || empty($data)) {
            return ams_rt(1, '请填写用户信息');
        } elseif (!isset($data['username']) || !$data['username']) {
            return ams_rt(1, '请填写用户名');
        } elseif (!isset($data['password']) || !$data['password']) {
            return ams_rt(1, '请填写登录密码');
        } elseif (!($id) && (strlen($data['password']) < 6 || strlen($data['password']) > 12)) {
            return ams_rt(1, '密码必须在6-12位之间');
        } elseif (!isset($data['groupid']) || !$data['groupid'] || !$groups[$data['groupid']]) {

            if ($config['groupid'] && $groups[$config['groupid']]) {
                $data['groupid'] = $config['groupid'];
            } else {
                return ams_rt(1, '请填选择会员分组');
            }

        }

        $flag = $this->field_exitsts($this->tablename, 'username', $data['username'], $id);
        if ($flag) {
            return ams_rt(1, '用户已存在');
        }

        if (isset($data['phone']) && $data['phone']) {
            $flag = $this->field_exitsts($this->tablename, 'phone', $data['phone'], $id);
            if ($flag) {
                return ams_rt(1, '手机号已存在');
            } elseif (!ams_isphone($data['phone'])) {
                return ams_rt(1, '手机号格式错误');
            }
        }

        if (isset($data['email']) && $data['email']) {
            $data['email'] = strtolower($data['email']);

            if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
                return ams_rt(1, '邮箱格式错误');
            }
            $flag = $this->field_exitsts($this->tablename, 'email', $data['email'], $id);
            if ($flag) {
                return ams_rt(1, '邮箱已存在');
            }
        }

        if (isset($data['avatar']) && $data['avatar']) {
            $row = $this->db->table('attachment')->select('related')->where('id', intval($data['avatar']))->get()->getRowArray();
            if ($row['related'] && !$id) {
                return ams_rt(1, '头像错误,请重新上传');
            }
        }

        return ams_rt(0, 'ok', $data);
    }

    private function _where(&$select, $data)
    {
        if ($data) {
            if (isset($data['groupid']) && (int) $data['groupid']) {
                $select->where('groupid', (int) $data['groupid']);
            }

            if (isset($data['email']) && $data['email']) {
                $select->where('email', $data['email']);
            }

            if (isset($data['username']) && $data['username']) {
                $select->where('username', $data['username']);
            }

            //状态
            if (isset($data['status']) && ($data['status'] || $data['status'] == '0')) {
                $select->where('status', (int) $data['status']);
            }

            // 时间搜索
            if (isset($data['start']) && $data['start'] && isset($data['end']) && $data['end']) {
                $start = strtotime($data['start'] . ' 00:00:00');
                $end = strtotime($data['end'] . ' 23:59:59');
                $select->where('`inputtime` BETWEEN ' . $start . ' AND ' . $end);
            }
        }
        return $data;
    }

    public function limit_page($page = 0, $size = 10, $total = 0, $param = [])
    {

        $page = max(1, (int) $page);
        $total = (int) $total;
        unset($param['page']);
        if ($param) {
            $param = esc($param);
        }
        if ($size > 0 && !$total) {
            $select = $this->db->table($this->tablename)->select('count(*) as total');
            $param = $this->_where($select, $param);
            $query = $select->get();

            if (!$query) {
                log_message('error', '数据查询失败：' . $this->tablename);
                return [[], $total, $param];
            }
            $data = $query->getRowArray();
            $total = (int) $data['total'];
            $param['total'] = $total;
            unset($select);
            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table($this->tablename);
        $param = $this->_where($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy('id', 'desc')->get();
        if (!$query) {
            log_message('error', '数据查询失败：' . $this->tablename);
            return [[], $total, $param];
        }
        $data = $query->getResultArray();
        if ($data) {
            foreach ($data as $k => $v) {
                $data[$k]['regtime_date'] = $v['regtime'] ? date('Y-m-d H:i:s', $v['regtime']) : '';
            }
        }
        $param['total'] = $total;
        return [$data, $total, $param];
    }

    /**
     * 用户注册
     *
     * @param   用户组
     * @param   注册账户信息
     * @param   自定义字段信息
     * @param   是否注册到服务器
     */
    public function add($user, $groupid = 1)
    {
        $rt = $this->_validate($user);
        if ($rt['code']) {
            return $rt;
        }
        $user = $rt['data'];
        if (!isset($user['groupid'])) {
            $user['groupid'] = $groupid;
        }

        // 默认注册组
        $user['salt'] = ams_salt();
        $user['password'] = $user['password'] ? md5(sha1($user['password']) . $user['salt'] . sha1($user['password'])) : '';
        $user['money'] = 0;
        $user['freeze'] = 0;
        $user['spend'] = 0;
        $user['score'] = 0;
        $user['experience'] = 0;
        $user['regip'] = $this->request->getIPAddress();
        $user['regtime'] = time();
        $user['randcode'] = rand(100000, 999999);

        //认证
        $user['iscomplete'] = 0;
        $user['istruename'] = 0;
        $user['ismobile'] = 0;
        $user['isemail'] = 0;

        $this->db->table($this->tablename)->insert($user);
        $uid = $this->db->insertID();
        if (!$uid) {
            return ams_rt(1, '用户注册失败');
        }
        $user['userid'] = $uid;
        // 注册后的关联
        // 更新邀请码
        $user['invitecode'] = $this->createInvitecode($uid, $user['username']);

        $this->session->set('user', $user);
        $this->session->set('userid', $uid);

        return ams_rt(0, '用户注册成功', $user);
    }

    public function createInvitecode($userid = 0, $username = '')
    {
        do {
            $code = ams_invite_code(12, $username . $userid);
            $count = $this->db->table($this->tablename)->where('invitecode', $code)->countAllResults();
        } while ($count);

        return $code;
    }

    public function getinfo($id)
    {
        $id = intval($id);
        $data = $this->db->table($this->tablename)->where('id', $id)->limit(1)->get()->getRowArray();
        if (!$data) {
            $data = [];
        } else {
            if ($data['avatar']) {
                $att = $this->db->table('attachment')->where('id', intval($data['avatar']))->get()->getRowArray();
                $data['avatar_url'] = (isset($att['attachment']) && $att['attachment']) ? thumb($att['attachment']) : SITE_URL . 'public\assets\image\noavatar_xs.gif';
                $data['avatar_info'] = $att;
            } else {
                $data['avatar_url'] = SITE_URL . 'public\assets\image\noavatar_xs.gif';
            }
        }
        return $data;
    }

    /**
     * 修改信息 $edit 新数据
     */
    public function edit($id, $data)
    {
        $rt = $this->_validate($data);
        if ($rt['code']) {
            return $rt;
        }
        $data = $rt['data'];
        $user = $this->db->table($this->tablename)->where('id', $id)->get()->getRowArray();
        if (!$user) {
            return ams_rt(1, '用户不存在', $data);
        }

        if ($data['password']) {
            $salt = $user['salt'];
            $password = md5(sha1($data['password']) . $salt . sha1($data['password']));
        }

        $this->db->table($this->tablename)->where('id', $id)->update($data);
        if ($this->db->affectedRows()) {
            return ams_rt(0, 'ok', $id);
        }
        return ams_rt(1, '操作失败');
    }

    public function setAvatar($id, $avatar)
    {
        $id = intval($id);
        $user = $this->db->table($this->tablename)->select('avatar')->where('id', $id)->get()->getRowArray();
        if (!$user) {
            return ams_rt(1, '用户不存在', $data);
        }

        $this->db->table($this->tablename)->where('id', $id)->update(['avatar' => $avatar]);
        if ($this->db->affectedRows()) {
            return ams_rt(0, '操作成功', $id);
        }
        return ams_rt(1, '操作失败');
    }

    //修改基本信息
    public function setProfile($id, $data = [])
    {
        $data = esc($data);

        $id = intval($id);
        $user = $this->db->table($this->tablename)->select('id,username,email,signs,nickname')->where('id', $id)->get()->getRowArray();
        if (!$user) {
            return ams_rt(1, '用户不存在', $data);
        }
        ams_clean_xss($data);
        $udata = [
            'nickname' => isset($data['nickname']) ? $data['nickname'] : '',
            'sex' => isset($data['sex']) ? intval($data['sex']) : 0,
            'signs' => isset($data['signs']) ? $data['signs'] : '',
            'email' => isset($data['email']) ? $data['email'] : '',
        ];
        $this->db->table($this->tablename)->where('id', $id)->update($udata);
        if ($this->db->affectedRows()) {
            return ams_rt(0, '操作成功', $id);
        }
        return ams_rt(1, '操作失败');
    }

    //修改密码
    public function setPassword($userid, $data = [])
    {

        $data = esc($data);

        $userid = intval($userid);
        $user = $this->db->table($this->tablename)->select('id,username,salt,password')->where('id', $userid)->get()->getRowArray();
        if (!$user) {
            return ams_rt(1, '用户不存在', $data);
        }

        if ($user['password'] != md5(sha1($data['nowpass']) . $user['salt'] . sha1($data['nowpass']))) {
            return ams_rt(1, '旧密码不正确', $data);
        } elseif ($data['pass'] != $data['repass']) {
            return ams_rt(1, '两次密码不一致', $data);
        }

        $password = md5(sha1($data['pass']) . $user['salt'] . sha1($data['pass']));
        $this->db->table($this->tablename)->where('id', $userid)->update(['password' => $password]);
        if ($this->db->affectedRows()) {
            $this->session->set('userid', 0);
            $this->session->set('user', null);
            return ams_rt(0, '操作成功', $userid);
        }
        return ams_rt(1, '操作失败');
    }

    public function del($id = 0)
    {
        if (!$id) {
            return ams_rt(1, '操作失败:参数错误');
        }
        $row = $this->db->table($this->tablename)->where('id', intval($id))->get()->getRowArray();
        if ($row) {
            $this->db->table($this->tablename)->where('id', intval($id))->delete();
        }
        return ams_rt(0, 'ok', $row);
    }

    public function getGroups()
    {
        $rows = $this->db->table($this->tablename . '_group')->where('status', 1)->get()->getResultArray();
        if (!$rows) {
            $data = [];
        } else {
            foreach ($rows as $v) {
                $data[$v['id']] = $v;
            }
        }
        return $data;
    }

    public function checkUserCookie($user = [])
    {
        // 获取本地认证cookie
        $cookie = get_cookie('user_cookie');
        // 授权登陆时不验证
        if ($user['id'] && $this->session->get('user_auth_uid') == $user['id']) {
            return 1;
        } elseif (!$cookie) {
            return 0;
        } elseif (substr(md5(SITE_KEY . $user['password']), 5, 20) !== $cookie) {
            return 0;
        }

        return 1;
    }

    /**
     * 取会员COOKIE
     */
    public function getUidBySession()
    {
        $userid = $this->session->get('userid'); //当前登录

        // $code = $this->session->get('admin_login_user_ids'); //后台授权登录
        $ids = ams_get_cookie('admin_login_user_ids');
        if ($ids) {
            list($uid, $adminid) = explode('-', $ids);
            $uid = (int) $uid; //后台登录管理员登录的用户
            if ($userid != $uid) {
                $admin = $this->db->table('admin')->select('uid,username,password')->where('uid', (int) $adminid)->get()->getRowArray();
                if ($admin && $this->session->get('admin_login_user_code') == md5($uid . sha1($admin['uid'] . $admin['password']))) {
                    $userid = $uid;
                }
            }
        }
        if (!$userid) {
            return 0;
        }
        return $userid;
    }

    /**
     * 由用户名获取uid
     */
    public function uid($name)
    {
        if ($name == $this->user['username']) {
            return $this->user['userid'];
        }
        $data = $this->db->table('user')->select('id')->where('username', esc($name))->get()->getRowArray();
        return intval($data['id']);
    }

    /**
     * 由uid获取用户名
     */
    public function username($uid)
    {
        if ($uid == $this->user['userid']) {
            return $this->user['username'];
        }
        $data = $this->db->table('user')->select('username')->where('id', intval($uid))->get()->getRowArray();
        return $data['username'];
    }

    /**
     * 由uid获取电话
     */
    public function phone($uid)
    {
        if ($uid == $this->user['userid']) {
            return $this->user['phone'];
        }
        $data = $this->db->table('user')->select('phone')->where('id', intval($uid))->get()->getRowArray();
        return $data['phone'];
    }

    // 用户基本信息
    public function userInfo($uid)
    {
        if ($uid == $this->user['userid']) {
            return $this->user;
        }
        $data = $this->db->table('user')->where('id', intval($uid))->get()->getRowArray();
        $data['userid'] = $data['id'];
        return $data;
    }

    /**
     * 登录记录
     *
     * @param    intval    $data        会员
     * @param    string    $OAuth        登录方式
     */
    private function _login_log($data, $type = '')
    {

        $ip = $this->request->getIPAddress();
        if (!$ip || !$data['userid']) {
            return false;
        }

        $agent = $this->request->getUserAgent();
        if (strlen($agent) <= 5) {
            return false;
        }

        $log = [
            'userid' => $data['userid'],
            'type' => $type,
            'loginip' => $ip,
            'logintime' => time(),
            'useragent' => substr($agent, 0, 255),
        ];

        $this->db->table($this->tablename . '_login')->insert($log);
    }

    /**
     * 初始化处理
     */
    public function initUser($user)
    {

        if (!$user) {
            return;
        }

        // 明天凌晨时间戳

        // 每日登录积分处理

        // 每日登录金币处理
    }

    /**
     * 授权登录信息
     */
    public function oauth($uid)
    {

        $data = $this->db->table('user_oauth')->where('userid', $uid)->get()->getResultArray();
        if (!$data) {
            return [];
        }

        $rt = [];
        foreach ($data as $t) {
            $rt[$t['oauth']] = $t;
        }

        return $rt;
    }

    /**
     * 会员信息
     */
    public function getUser($uid = 0, $username = '')
    {
        $uid = intval($uid);
        $data = null;
        if ($uid) {
            $data = $this->db->table($this->tablename)->where('id', $uid)->get()->getRowArray();
        } elseif ($username) {
            $data = $this->db->table($this->tablename)->where('username', $username)->get()->getRowArray();
            $uid = (int) $data['id'];
        }
        if (!$data) {
            return null;
        }
        $data['authid'] = [];
        $data['adminid'] = (int) $data['adminid'];
        return $data;
    }

    // 获取authid
    public function authid($uid)
    {

        if (!$uid) {
            return [0];
        } elseif ($uid == $this->uid) {
            return \Phpcmf\Service::C()->user['authid'];
        }

        $rt = [];
        $data2 = $this->db->table('user_group_index')->where('userid', $uid)->get()->getResultArray();
        if ($data2) {
            foreach ($data2 as $t) {
                $rt[] = $t['lid'] ? $t['gid'] . '-' . $t['lid'] : $t['gid'];
            }
        }

        return $rt;
    }

    // 更新用户组
    // user 用户信息
    // groups 拥有的用户组
    public function update_group($user, $groups)
    {
    }

    // 手动变更等级
    public function update_level($uid, $gid, $lid)
    {

        // 挂钩点 用户组变更之后
    }

    /**
     * 添加一条通知
     * @param    string    $uid
     * @param    string    $note
     * @return    null
     */
    public function notice($uid, $type, $note, $url = '')
    {
        if (!$uid || !$note) {
            return '';
        }
        $uids = is_array($uid) ? $uid : explode(',', $uid);
        foreach ($uids as $uid) {
            $this->db->table('user_notice')->insert([
                'userid' => $uid,
                'type' => max(1, (int) $type),
                'isnew' => 1,
                'content' => $note,
                'url' => (string) $url,
                'inputtime' => SITE_TIME,
            ]);
        }

        return '';
    }

    /**
     * 系统提醒
     *
     * @param    site    站点id,公共部分0
     * @param    type    system系统  content内容相关  user会员相关 app应用相关 pay 交易相关
     * @param    msg     提醒内容
     * @param    uri     后台对应的链接
     * @param    to      通知对象 留空表示全部对象
     * array(
     *      to_uid 指定人
     *      to_rid 指定角色组
     * )
     */
    public function admin_notice($site, $type, $user, $msg, $uri, $to = [])
    {

        $this->db->table('admin_notice')->insert([
            'site' => (int) $site,
            'type' => $type,
            'msg' => $msg,
            'uri' => $uri,
            'to_rid' => intval($to['to_rid']),
            'to_uid' => intval($to['to_uid']),
            'status' => 0,
            'userid' => (int) $user['id'],
            'username' => $user['username'] ? $user['username'] : '',
            'op_uid' => 0,
            'op_username' => '',
            'updatetime' => 0,
            'inputtime' => time(),
        ]);
    }

    // 执行提醒
    public function todo_admin_notice($uri, $site = 0)
    {
        $this->db->table('admin_notice')->where('site', (int) $site)->where('uri', $uri)->update([
            'status' => 3,
            'updatetime' => time(),
        ]);
    }

    // 执行删除提醒
    public function delete_admin_notice($uri, $site = 0)
    {
        $this->db->table('admin_notice')->where('site', (int) $site)->where('uri', $uri)->delete();
    }

    // 审核用户
    public function verify_user($uid)
    {

        $this->db->table('user_data')->where('id', $uid)->update(['is_verify' => 1]);
        // 后台提醒
        $this->todo_admin_notice('user_verify/index:field/id/keyword/' . $uid, 0);
    }

    /**
     * 存储cookie
     */
    public function save_cookie($data, $reuser = 0)
    {
        $row = $this->db->table($this->tablename)->select('id,password,salt')->where('id', $data['userid'])->get()->getRowArray();
        // 存储cookie
        $expire = $reuser ? 8640000 : WEEK;
        set_cookie('userid', $data['userid'], $expire);
        set_cookie('user_cookie', substr(md5($data['userid'] . $row['password']), 5, 20), $expire);
    }

    /**
     * 退出登录
     */
    public function logout()
    {
        // 注销授权登陆的会员
        if ($this->session->get('user_auth_uid')) {
            $this->session->remove('user_auth_uid');
        }
        $this->session->remove('userid');
        $this->session->remove('user');
        set_cookie('userid', 0, 1);
        set_cookie('user_cookie', '', 1);
        return true;
    }

    // 查询会员信息
    public function getUserInfo($username)
    {
        $data = $this->db->table($this->tablename)->where('username', $username)->get()->getRowArray();
        if (!$data) {
            return [];
        }
        $data['userid'] = $data['id'];
        return $data;
    }

    // 验证管理员登录权限
    private function _is_admin_login_user($uid)
    {
        if (!$uid) {
            return ams_rt(1, 'ok');
        }
        if ($this->db->table('admin')->where('id', $uid)->countAllResults()) {
            return ams_rt(0, '管理员账号不允许前台登录');
        }
        return ams_rt(1, 'ok');
    }

    /**
     * 验证登录
     *
     * @param    string    $username    用户名
     * @param    string    $password    明文密码
     * @param    intval    $remember    是否记住密码(时间)
     */
    public function login($username, $password, $remember = 0)
    {

        if (!$username) {
            return ams_rt(1, '请填写用户名');
        } elseif (!$password) {
            return ams_rt(1, '请填写登录密码');
        }

        $data = $this->getUserInfo($username);
        if (!$data) {
            return ams_rt(1, '用户名或者密码不正确');
        }

        // 密码验证
        $password = ams_safe_password($password);
        if (md5(sha1($password) . $data['salt'] . sha1($password)) != $data['password']) {
            return ams_rt(1, '用户名或者密码不正确');
        }

        // 保存本地会话
        $this->session->set('userid', $data['userid'], WEEK);
        $this->session->set('user', $data);
        ams_set_cookie('userid', $data['userid'], WEEK);

        // 登录日志
        $this->_login_log($data);
        return ams_rt(0, '登录成功', $data);
    }

    // 绑定注册模式 授权注册绑定
    public function register_oauth_bang($oauth, $groupid, $data)
    {

        if (!$oauth) {
            return ams_rt(1, 'OAuth数据不存在，请重试');
        }

        $row = $this->db->table($this->tablename . '_oauth')->where('id', $oauth['id'])->get()->getRowArray();
        //已经绑定过了
        if (!$row['userid']) {
            $rt = $this->register($data, $groupid);
            if ($rt['code']) {
                return ams_rt(1, $rt['msg']);
            }
            $user = $rt['data'];
        } else {
            $user = $this->getinfo($row['userid']);
        }

        // 保存本地会话
        $this->save_cookie($user);

        // 记录日志
        $this->_login_log($user, $oauth['oauth']);

        // 更改状态
        $this->db->table($this->tablename . '_oauth')->where('id', $oauth['id'])->update(['userid' => $user['userid'], 'avatar' => $row['avatar']]);

        return ams_rt(0, 'ok', $user);
    }

    // 直接登录模式 授权注册
    public function register_oauth($groupid, $oauth)
    {
        $name = $oauth['nickname'];
        $user = [
            'username' => $name,
            'name' => $name,
            'email' => '',
            'phone' => '',
        ];

        $count = $this->db->table($this->tablename)->where('username', $user['username'])->countAllResults();
        $count && $user['username'] .= '_' . $oauth['oauth'] . '_' . rand(0, 9999);

        $rt = $this->register($user, $groupid);
        if (!$rt['code']) {
            return ams_rt(0, $rt['msg']);
        }

        $data = $rt['data'];

        // 保存本地会话
        $this->save_cookie($data);

        // 记录日志
        $this->_login_log($data, $oauth['oauth']);

        // 更改状态
        $this->db->table('user_oauth')->where('id', $oauth['id'])->update(['userid' => $data['id']]);

        // 下载头像和同步登录
        return ams_rt(0, 'ok', $data);
    }

    /**
     * 用户注册
     *
     * @param   用户组
     * @param   注册账户信息
     * @param   自定义字段信息
     * @param   是否注册到服务器
     */
    public function register($user, $groupid = 1)
    {
        $rt = $this->_validate($user);
        if ($rt['code']) {
            return $rt;
        }

        $config = $this->getConfig();
        $groups = $this->getGroups();
        $user = $rt['data'];

        $data['status'] = 1; //默认正常

        if (!isset($user['groupid']) || !$user['groupid'] || !$groups[$user['groupid']]) {
            if ($config['groupid'] && $groups[$config['groupid']]) {
                $user['groupid'] = $config['groupid'];
            } elseif ($groupid && $groups[$groupid]) {
                $user['groupid'] = $groupid;
            } else {
                return ams_rt(1, '请选择用户组');
            }
        }

        $rt = $this->checkReg($user);
        if ($rt['code']) {
            return $rt;
        } else {
            $user = $rt;
        }

        // 默认注册组
        $user['salt'] = ams_salt();
        $user['password'] = $user['password'] ? md5(sha1($user['password']) . $user['salt'] . sha1($user['password'])) : '';
        $user['money'] = 0;
        $user['freeze'] = 0;
        $user['spend'] = 0;
        $user['score'] = 0;
        $user['experience'] = 0;
        $user['regip'] = $this->request->getIPAddress();
        $user['regtime'] = time();
        $user['randcode'] = rand(100000, 999999);
        //认证
        $user['iscomplete'] = 0;
        $user['istruename'] = 0;
        $user['ismobile'] = 0;
        $user['isemail'] = 0;

        $this->db->table($this->tablename)->insert($user);
        $uid = $this->db->insertID();
        if (!$uid) {
            return ams_rt(1, '用户注册失败');
        }
        $user['userid'] = $uid;

        $this->session->set('user', $user);
        $this->session->set('userid', $uid);

        unset($user['password'], $user['salt'], $user['randcode']);

        return ams_rt(0, '用户注册成功', $user);
    }

    /**
     * 存储授权信息
     */
    public function insertOauth($data)
    {

        $row = $this->db->table('user_oauth')->where('openid', $data['openid'])->where('oauth', $data['oauth'])->get()->getRowArray();
        if (!$row) {
            // 插入授权信息
            $this->db->table('user_oauth')->insert($data);
            $id = $this->db->insertID();
            if (!$id) {
                return ams_rt(1, '服务器错误');
            }
        } else {
            $data['userid'] = $row['userid'];
            // 更新授权信息
            $this->db->table('user_oauth')->where('id', $row['id'])->update($data);
            $id = $row['id'];
        }
        $data['id'] = $id;
        // 存储session
        $this->session->set('user_auth_' . $data['oauth'], $id);
        if ($data['userid']) {
            $user = $this->getinfo($data['userid']);
            $data = array_merge($data, $user);
        }

        return ams_rt(0, 'ok', $data);
    }

    //通过openid获取详情
    public function getProfileByOpenid($openid)
    {
        $row = $this->db->table($this->tablename . '_oauth')->where('openid', $openid)->get()->getRowArray();
        if (!$row) {
            return false;
        }
        if ($row['userid']) {
            $user = $this->getinfo($row['userid']);
        } else {
            $user = [];
        }
        unset($row['refresh_token'], $row['access_token'], $row['expire_at'], $row['unionid']);
        $data = array_merge($row, $user);
        return $data;
    }

    /**
     * 邮件发送
     */
    public function sendmail($tomail, $subject, $msg, $data = [])
    {

        if (!$tomail || !$subject || !$msg) {
            return ams_rt(0, '参数错误');
        }

        $cache = $this->cacheLib->get('email');
        if (!$cache) {
            return ams_rt(0, '无邮件smtp配置');
        }

        $content = $msg;

        return ams_rt(0, 'Error：');
    }

    /**
     * 获取微信 access token
     */
    public function _weixin_template_access_token()
    {

        $cache_data = $this->cacheLib->init('file')->get('access_token');
        if (isset($cache_data['time']) && $cache_data['access_token']) {
            $access_token = $cache_data['access_token'];
        } else {
            $weixin = \Phpcmf\Service::C()->get_cache('weixin');
            $result = wx_get_https_json_data('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $weixin['account']['appid'] . '&secret=' . $weixin['account']['appsecret']);
            if (!$result['code']) {
                return ams_rt(0, 'AccessToken：' . $result['msg']);
            }
            $rt = $this->cacheLib->init('file')->save('access_token', $result['data'], 3600);
            if (!$rt) {
                return ams_rt(0, 'AccessToken：/cache/temp/目录不可写，文件写入失败');
            }
            $access_token = $result['data']['access_token'];
        }

        return ams_rt(1, 'ok', ['access_token' => $access_token]);
    }

    /**
     * 发送微信通知模板
     *
     * $uid    会员id
     * $id     微信模板id
     * $data    通知内容
     * $url    详细地址
     * $color    top颜色
     */
    public function wexin_template($uid, $id, $data, $url = '', $color = '')
    {
        $oauth = $this->db->table($this->tablename . '_oauth')->where('userid', $uid)->where('oauth', 'wechat')->get()->getRowArray();
        if (!$oauth) {
            return ams_rt(0, 'uid（' . $uid . '）未绑定账号');
        }

        $rt = $this->_weixin_template_access_token($id);
        if (!$rt['code']) {
            return ams_rt(0, $rt['msg']);
        }

        $p = [
            'touser' => $oauth['oid'],
            'template_id' => $id,
            'url' => $url,
            'topcolor' => $color,
            'data' => $data,
        ];
        $rt = wx_post_https_json_data('https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . $rt['data']['access_token'], $p);

        return $rt;
    }

    /**
     * 增加经验
     *
     * @param    intval    $uid    会员id
     * @param    intval    $value    分数变动值
     * @param    string    $mark    标记
     * @param    string    $note    备注
     * @param    intval    $count    统计次数
     * @return    intval
     */
    public function add_experience($uid, $val, $note = '', $url = '', $mark = '', $count = 0)
    {

        if (!$uid || !$val) {
            return ams_rt(0, '参数错误');
        }

        $user = $this->user_info($uid);
        if (!$user) {
            return ams_rt(0, '用户不存在');
        }

        // 判断次数
        if ($mark && $count && $this->db->table('user_explog')->where('userid', $uid)->where('mark', $mark)->countAllResults() >= $count) {
            return ams_rt(0, '本次不能累计增减金币');
        }

        $val = abs($val); // 经验值只能加
        $value = max(0, (int) $user['experience'] + $val); // 不允许小于0
        $this->db->table('user')->where('id', (int) $uid)->update(['experience' => $value]);

        // 交易记录
        return $this->table('user_explog')->insert([
            'userid' => $uid,
            'username' => $user['username'],
            'url' => $url ? $url : '',
            'mark' => $mark ? $url : '',
            'note' => $note,
            'value' => $val,
            'inputtime' => SITE_TIME,
        ]);
    }

    /**
     * 增加金币
     *
     * @param    intval    $uid    会员id
     * @param    intval    $value    分数变动值
     * @param    string    $mark    标记
     * @param    string    $note    备注
     * @param    intval    $count    统计次数
     * @return    intval
     */
    public function add_score($uid, $val, $note = '', $url = '', $mark = '', $count = 0)
    {

        if (!$uid || !$val) {
            return ams_rt(0, '参数错误');
        }

        $user = $this->user_info($uid);
        if (!$user) {
            return ams_rt(0, '用户不存在');
        }

        // 判断次数
        if ($mark && $count && $this->db->table('user_scorelog')->where('userid', $uid)->where('mark', $mark)->countAllResults() >= $count) {
            return ams_rt(0, '本次不能累计增减金币');
        }

        $value = max(0, (int) $user['score'] + $val); // 不允许小于0
        $this->db->table('user')->where('id', (int) $uid)->update(['score' => $value]);

        // 交易记录
        return $this->table('user_scorelog')->insert([
            'userid' => $uid,
            'username' => $user['username'],
            'url' => $url ? $url : '',
            'mark' => $mark ? $mark : '',
            'note' => $note,
            'value' => $val,
            'inputtime' => SITE_TIME,
        ]);
    }

    // 增加money
    public function add_money($uid, $value)
    {

        $value = floatval($value);
        if (!$value) {
            return ams_rt(0, '金额不正确');
        }

        $user = $this->user_info($uid);
        if (!$user) {
            return ams_rt(0, '用户不存在');
        }

        $update = [
            'money' => max(0, $user['money'] + $value),
        ];
        $value < 0 && $update['spend'] = max(0, $user['spend'] + abs($value));

        $rt = $this->table('user')->update($uid, $update);

        return $rt;
    }

    // 冻结资金
    public function add_freeze($uid, $value)
    {

        $value = floatval(abs($value));
        if (!$uid || !$value) {
            return ams_rt(0, '参数不正确');
        }

        $rt = $this->query('update `' . $this->dbprefix('user') . '` set `money`=`money`-' . $value . ',`freeze`=`freeze`+' . $value . ' where id=' . $uid);
        return $rt;
    }

    // 取消冻结资金
    public function cancel_freeze($uid, $value)
    {
        $value = floatval(abs($value));
        if (!$uid || !$value) {
            return ams_rt(0, '参数不正确');
        }
        $rt = $this->db->table($this->tablename)->where('id', $uid)->set('money', 'money+' . $value, false)->set('freeze', 'freeze-' . $value, false)->update();
        return $rt;
    }

    // 用户系统缓存
    public function cache()
    {
        $cache = [];
        // 获取会员全部配置信息
        $result = $this->db->table('user_setting')->get()->getResultArray();
        if ($result) {
            foreach ($result as $t) {
                $cache[$t['name']] = json_decode($t['value'], true);
            }
        }
        $this->cacheLib->set_file('user', $cache);
    }

    public function setConfig($data)
    {
        $param = 'user';
        $config = [
            'complete' => 1, //是否必须资料完善
            'ismobile' => 1, //是否必须手机认证
            'isemail' => 1, //是否必须邮箱认证
            'istruename' => 1, //是否必须实名认证
            'register' => 1, //是否允许注册
            'regverify' => 1, //注册后需要审核
            'regiptime' => 1, //注册间隔小时
            'regnamerule' => '', //username规则
            'regnotallow' => '', //不允许注册名
        ];
        foreach ($config as $k => $v) {
            if (!isset($data[$k])) {
                unset($data[$k]);
            }
        }
        $this->db->table('setting')->replace(['param' => $param, 'value' => json_encode($data), 'updatetime' => time()]);
        return ams_rt(0, '操作成功');
    }

    //获取设置
    public function getConfig()
    {
        $data = $this->cache->get('user_config');
        if ($data) {
            return $data;
        }
        $data = $this->db->table('setting')->where('param', 'user')->get()->getRowArray();
        if (!$data) {
            $data = [];
        } else {
            $data = json_decode($data['value'], true);
            $this->cache->save('user_config', $data, YEAR);
        }
        return $data;
    }

    // 注册或添加验证账号
    public function checkUserName($value)
    {
        $config = $this->getConfig();
        if (!$value) {
            return ams_rt(1, '账号不能为空', ['field' => 'username']);
        } elseif ($config['preg']
            && !preg_match($config['preg'], $value)) {
            return ams_rt(1, '账号格式不正确', ['field' => 'username']);
        } elseif ($config['notallow']
            && in_array($value, $config['notallow'])) {
            return ams_rt(1, '账号名不允许注册', ['field' => 'username']);
        } elseif (strpos($value, '"') !== false || strpos($value, '\'') !== false) {
            return ams_rt(1, '账号名存在非法字符', ['field' => 'username']);
        } elseif ($config['userlen']
            && mb_strlen($value) < $config['userlen']) {
            return ams_rt(1, '账号长度不能小于' . $config['userlen'] . '位', ['field' => 'username']);
        }

        return ams_rt(0, 'ok');
    }

    // 注册或添加验证账号的密码
    public function checkPassWord($value, $username)
    {
        $config = $this->getConfig();
        if (!$value) {
            return ams_rt(1, '密码不能为空', ['field' => 'password']);
        } elseif (!$config['user2pwd'] && $value == $username) {
            return ams_rt(1, '密码不能与账号相同', ['field' => 'password']);
        } elseif ($config['pwdpreg']
            && !preg_match(trim($config['pwdpreg']), $value)) {
            return ams_rt(1, '密码格式不正确', ['field' => 'password']);
        } elseif ($config['pwdlen']
            && mb_strlen($value) < $config['pwdlen']) {
            return ams_rt(1, '密码长度不能小于' . $config['pwdlen'] . '位', ['field' => 'password']);
        }

        return ams_rt(0, 'ok');
    }

    //注册设置
    public function checkReg($data = [])
    {
        $config = $this->getConfig();
        if ($config['register'] == 0) {
            return ams_rt(1, '系统已关闭注册');
        }

        if ($config['invitecode'] == 1) {
            $invitecode = $this->session->get('invitecode');
            if (!$invitecode && (!isset($data['invitecode']) || !$data['invitecode'])) {
                return ams_rt(1, '必须有邀请码才能注册');
            }
        }

        if ($config['regverify'] == 1) {
            $data['status'] == 2;
        }

        if ($config['regnotallow']) {
            $not = explode(',', $config['regnotallow']);
            if (is_array($not) && in_array($data['username'], $not)) {
                return ams_rt(1, $data['username'] . '请更换用户名试试');
            }
        }

    }

    /**用户组**/
    //验证
    private function _validateGroup($data, $id = 0)
    {
        ams_clean_xss($data);

        if (!isset($data) || empty($data)) {
            return ams_rt(1, '请填写用户信息');
        } elseif (!isset($data['name']) || !$data['name']) {
            return ams_rt(1, '请填写分组名称');
        }

        if (isset($data['email']) && $data['email']) {
            $data['email'] = strtolower($data['email']);
        }

        $flag = $this->field_exitsts($this->tablename . '_group', 'name', $data['name'], $id);
        if ($flag) {
            return ams_rt(1, '分组名称已存在');
        }

        if (isset($data['phone']) && $data['phone']) {
            $flag = $this->field_exitsts($this->tablename . '_group', 'phone', $data['phone'], $id);
            if ($flag) {
                return ams_rt(1, '手机号已存在');
            } elseif (!ams_isphone($data['phone'])) {
                return ams_rt(1, '手机号格式错误');
            }
        }

        return ams_rt(0, 'ok', $data);
    }

    private function _where_group(&$select, $data)
    {
        if ($data) {
            if (isset($data['id']) && (int) $data['id']) {
                $select->where('id', (int) $data['id']);
            }

            //状态
            if (isset($data['status']) && ($data['status'] || $data['status'] == '0')) {
                $select->where('status', (int) $data['status']);
            }

        }
        return $data;
    }

    public function limit_page_group($page = 0, $size = 10, $total = 0, $param = [])
    {

        $page = max(1, (int) $page);
        $total = (int) $total;
        unset($param['page']);
        if ($param) {
            $param = esc($param);
        }
        if ($size > 0 && !$total) {
            $select = $this->db->table($this->tablename . '_group')->select('count(*) as total');
            $param = $this->_where_group($select, $param);
            $query = $select->get();

            if (!$query) {
                log_message('error', '数据查询失败：' . $this->tablename . '_group');
                return [[], $total, $param];
            }
            $data = $query->getRowArray();
            $total = (int) $data['total'];
            $param['total'] = $total;
            unset($select);
            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table($this->tablename . '_group');
        $param = $this->_where_group($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy('id', 'desc')->get();
        if (!$query) {
            log_message('error', '数据查询失败：' . $this->tablename . '_group');
            return [[], $total, $param];
        }
        $data = $query->getResultArray();
        $param['total'] = $total;
        return [$data, $total, $param];
    }

    public function addGroup($data)
    {
        $rt = $this->_validateGroup($data);
        if ($rt['code']) {
            return $rt;
        }
        $idata = array(
            'name' => $data['name'],
            'price' => isset($data['price']) ? $data['price'] : 0,
            'unit' => isset($data['unit']) ? $data['unit'] : 1,
            'limit' => isset($data['limit']) ? $data['limit'] : '',
            'overdue' => isset($data['overdue']) ? intval($data['overdue']) : 0,
            'allowregister' => isset($data['allowregister']) && $data['allowregister'] ? 1 : 0,
            'displayorder' => isset($data['displayorder']) ? intval($data['displayorder']) : 0,
            'status' => isset($data['status']) && $data['status'] ? 1 : 0,
        );
        $this->db->table($this->tablename . '_group')->insert($idata);
        $id = $this->db->insertID();
        if ($id) {
            $data['id'] = $id;
            return ams_rt(0, '操作成功', $data);
        }
        return ams_rt(1, '操作失败', $data);
    }

    public function editGroup($id, $data)
    {
        $rt = $this->_validateGroup($data, $id);
        if ($rt['code']) {
            return $rt;
        }
        $idata = array(
            'name' => $data['name'],
            'price' => isset($data['price']) ? $data['price'] : 0,
            'unit' => isset($data['unit']) ? $data['unit'] : 1,
            'limit' => isset($data['limit']) ? $data['limit'] : '',
            'overdue' => isset($data['overdue']) ? intval($data['overdue']) : 0,
            'allowregister' => isset($data['allowregister']) && $data['allowregister'] ? 1 : 0,
            'displayorder' => isset($data['displayorder']) ? intval($data['displayorder']) : 0,
            'status' => isset($data['status']) && $data['status'] ? 1 : 0,
        );
        $this->db->table($this->tablename . '_group')->where('id', $id)->update($idata);
        if ($this->db->affectedRows()) {
            return ams_rt(0, '操作成功', $data);
        }
        return ams_rt(1, '操作失败', $data);
    }

    public function getLimitArr()
    {
        $data = [
            'hour', 'day', 'month', 'year', 'ever',
        ];
        return $data;
    }

    public function getGroupInfo($id)
    {
        $id = intval($id);
        $data = $this->db->table($this->tablename . '_group')->where('id', $id)->limit(1)->get()->getRowArray();
        if ($data['thumb']) {
            $att = $this->db->table('attachment')->where('id', intval($data['thumb']))->get()->getRowArray();
            $data['thumb_info'] = $att;
        }
        return ams_rt(0, 'ok', $data);
    }

    public function getGroupSelect()
    {
        $data = $this->db->table($this->tablename . '_group')->where('status', 1)->get()->getResultArray();
        if (!$data) {
            $data = [];
        }
        return $data;
    }

    public function delGroup($id = 0)
    {
        if (!$id) {
            return ams_rt(1, '操作失败:参数错误');
        }
        $row = $this->db->table($this->tablename . '_group')->where('id', intval($id))->get()->getRowArray();
        if ($row) {
            $this->db->table($this->tablename . '_group')->where('id', intval($id))->delete();
        }
        return ams_rt(0, 'ok', $row);
    }

    public function getGroupById($id)
    {
        $id = intval($id);
        $data = $this->db->table($this->tablename . '_group')->where('id', $id)->get()->getRowArray();
        if (!$data) {
            $data = [];
        }
        return $data;
    }

    public function test($str)
    {
        \CodeIgniter\Events\Events::trigger('sforder', $str);
    }

}
